// uvm_tb/agent/binary_alu_monitor.sv
`ifndef BINARY_ALU_MONITOR_SV
`define BINARY_ALU_MONITOR_SV

class binary_alu_monitor extends uvm_monitor;

    // ========================================================================
    // Data Members
    // ========================================================================
    protected virtual binary_alu_if vif;
    uvm_analysis_port #(binary_alu_transaction) item_collected_port;

    // ========================================================================
    // UVM Macros
    // ========================================================================
    `uvm_component_utils(binary_alu_monitor)

    // ========================================================================
    // Constructor
    // ========================================================================
    function new(string name, uvm_component parent);
        super.new(name, parent);

    endfunction

    // ========================================================================
    // UVM Build Phase
    // ========================================================================
    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        if (!uvm_config_db#(virtual binary_alu_if)::get(this, "", "vif", vif))
            `uvm_fatal("NOVIF", "Virtual interface must be set for binary_alu_monitor")
        item_collected_port = new("item_collected_port", this);
    endfunction

    // ========================================================================
    // UVM Run Phase
    // ========================================================================
    virtual task run_phase(uvm_phase phase);
        super.run_phase(phase);

        // Initialize output ready signal (before reset)
        vif.right_rdy = 1'b0;  // Initially not ready

        // Wait for reset to complete
        @(posedge vif.rst_n);
        `uvm_info("MONITOR", "Reset released, monitor ready", UVM_LOW)

        // Now ready to receive outputs
        vif.right_rdy = 1'b1;  // Ready to accept DUT outputs

        sample_port("Monitor");
    endtask

    virtual task sample_port(string tag = "");
        forever begin
            @(posedge vif.clk);


            if (vif.right_vld && vif.right_rdy) begin
                binary_alu_transaction trans = binary_alu_transaction::type_id::create("trans");
                trans.expected_data = vif.right_dat;
                trans.expected_sdb  = vif.right_sdb;

                `uvm_info("MONITOR", $sformatf("T=%0t [%s] Collected output transaction", $time, tag), UVM_LOW)
                trans.print();

                item_collected_port.write(trans);
                `uvm_info("MONITOR", "Transaction sent to scoreboard", UVM_MEDIUM)
            end
        end

    endtask

endclass : binary_alu_monitor

`endif  // BINARY_ALU_MONITOR_SV
